# setting up the Multiboot header - see GRUB docs for details

#include <kern/mmu.h>
#include <kern/memlayout.h>


.global loader

.set ALIGN,	1<<0			# align loaded modules on page boundaries
.set MEMINFO,	1<<1			# provide memory map
.set FLAGS,	ALIGN | MEMINFO		# this is the Multiboot 'flag' field
.set MAGIC,	0x1BADB002		# 'magic number' lets bootloader find the header
.set CHECKSUM,	-(MAGIC + FLAGS)	# checksum required
.set loader,	(_loader-KERNBASE)		# fix loader address to be its physical one


.text
# The Multuboot header
.align 4
	.long MAGIC
	.long FLAGS
	.long CHECKSUM


_loader:
	# set cr3 to point at the boot pgdir
	movl  $(bootpgdir-KERNBASE), %ecx
	movl  %ecx, %cr3

	# init bootpgdir
	# put the boot page table pa into edx
	movl  $(bootpgtbl-KERNBASE), %edx
	orl   $(PTE_U | PTE_W | PTE_P), %edx

	# create the mapping 0x00000000 -> 0x00000000
	movl  %edx, (%ecx)
	# create the mapping 0xF0000000 -> x000000000
	addl  $0xF00, %ecx
	movl  %edx, (%ecx)

	# set PG bit in CR0 to enable paging
	movl  %cr0, %ecx
	or    $(CR0_PG), %ecx
	movl  %ecx, %cr0

	# jump to the kernel virtual address
	# this must be an absolute jump since eip changes
	# from physical address 0x001000xx to virtual
	# address of start (0xF01000xx)
	lea  start, %ecx
	jmp   *%ecx

start:
	#movl  $(bootpgdir), %ecx	# clear identity mapping, we no longer need it
	#movl  $0x0, (%ecx)
 
	movl  $0x0, %ebp		# set frame pointer to 0 for backtrace
	movl  $(bootstacktop-4), %esp	# set up the stack

	addl  $(KERNBASE), %ebx		# Multiboot info struct
	movl  $(mb_info), %ecx
	movl  %ebx, (%ecx)


	push  %eax			# Multiboot magic number

	call kmain

hang:
	hlt		# halt machine should kernel return
	jmp hang

.data
	.align 0x4
	.globl	vpt
	.set	vpt, VPT
	.globl	vpd
	.set	vpd, (VPT + (VPT >> 10))


	.align 0x4
	.globl mb_info
	.set mb_info, 0x0

	.align PGSIZE
	.globl bootstack
bootstack:
	.space PGSIZE
	.globl bootstacktop
bootstacktop:

